package com.info3k.client.components;

import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.info3k.client.Info3K;

public class Pagination extends Composite implements HasValue<Integer>{	
	private Integer length;
	private Integer current;
	private Integer pageSize;
	
	private HorizontalPanel panel = new HorizontalPanel();
	
	private HorizontalPanel panelMain = new HorizontalPanel();
	
	private ListBox pageSizeList = new ListBox();
	
	private Pagination parent;
	
	public Pagination(Integer ps){
		this.pageSize = ps;
		this.parent = this;
		
		pageSizeList.addItem("2", "2");
		pageSizeList.addItem("5", "5");
		pageSizeList.addItem("10", "10");
		pageSizeList.addItem("25", "25");
		pageSizeList.addItem("50", "50");
		pageSizeList.addItem("100", "100");
		
		pageSizeList.setSelectedIndex(2);
		
		pageSizeList.addChangeHandler(new ChangeHandler(){
			public void onChange(ChangeEvent event) {
				pageSize = Integer.valueOf(pageSizeList.getValue(pageSizeList.getSelectedIndex()));
				setValue(0, true);
				render(0);
			}
		});
		
		initWidget(panelMain);
		
		panelMain.add(new Label(Info3K.msgs.resultsPerPage() + ": "));
		panelMain.add(pageSizeList);
		pageSizeList.getElement().getStyle().setMarginLeft(10, Unit.PX);
		pageSizeList.getElement().getStyle().setMarginRight(10, Unit.PX);
		pageSizeList.getElement().getStyle().setHeight(26, Unit.PX);
		panelMain.add(panel);
		panelMain.setVisible(false);
	}
	
	public void render(Integer current){
		this.current = current;
		panelMain.setVisible(true);
		panel.clear();
		if(getLength()/getPageSize()<6){
			for (int i = 0; i < getLength(); i=i+getPageSize()) {
				Button btn = new Button(String.valueOf((i/getPageSize()) + 1));
				if(btn.getText().equals(String.valueOf(current+1))) btn.setEnabled(false);
				btn.addClickHandler(new ClickHandler(){
					public void onClick(ClickEvent event) {
						Integer num = Integer.valueOf(((Button)event.getSource()).getText());
						setValue(num-1, true);
						render(num-1);
					}
				});
				panel.add(btn);
			}
		} else {
			long max = Math.round(getLength()/getPageSize() + 0.5);
			
			Button btn = new Button("1");
			btn.getElement().getStyle().setMarginLeft(2, Unit.PX);
			if(current==0) btn.setEnabled(false);
			Button btn1 = new Button(current.toString());
			Button btn2 = new Button(String.valueOf(current+1));
			Button btn3 = new Button(String.valueOf(current+2));
			Button btn4 = new Button(String.valueOf(max));
			panel.add(btn);
			if(current>1) panel.add(new HTML("..."));
			if(current>1) panel.add(btn1);
			if(current!=0) {
				panel.add(btn2);
				btn2.setEnabled(false);
			}
			
			if(current<max-2) panel.add(btn3);
			if(current<max-3) panel.add(new HTML("..."));
			if(current<max-1) panel.add(btn4);
			
			btn.addClickHandler(new ClickHandler(){
				public void onClick(ClickEvent event) {
					Integer num = Integer.valueOf(((Button)event.getSource()).getText());
					setValue(num-1, true);
					render(num-1);
				}
			});
			
			btn1.addClickHandler(new ClickHandler(){
				public void onClick(ClickEvent event) {
					Integer num = Integer.valueOf(((Button)event.getSource()).getText());
					setValue(num-1, true);
					render(num-1);
				}
			});
			
			btn2.addClickHandler(new ClickHandler(){
				public void onClick(ClickEvent event) {
					Integer num = Integer.valueOf(((Button)event.getSource()).getText());
					setValue(num-1, true);
					render(num-1);
				}
			});
			
			btn3.addClickHandler(new ClickHandler(){
				public void onClick(ClickEvent event) {
					Integer num = Integer.valueOf(((Button)event.getSource()).getText());
					setValue(num-1, true);
					render(num-1);
				}
			});
			
			btn4.addClickHandler(new ClickHandler(){
				public void onClick(ClickEvent event) {
					Integer num = Integer.valueOf(((Button)event.getSource()).getText());
					setValue(num-1, true);
					render(num-1);
				}
			});
		}
	}

	public void setLength(Integer length) {
		this.length = length;
	}

	public Integer getLength() {
		return length;
	}

	public void setPageSize(Integer pageSize) {
		this.pageSize = pageSize;
	}

	public Integer getPageSize() {
		return pageSize;
	}

	public Integer getValue() {
		return current;
	}

	public void setValue(Integer value) {
		current = value;
	}

	public void setValue(Integer value, boolean fireEvents) {
		current = value;
		if(fireEvents) ValueChangeEvent.fire(parent, getValue());
	}

	public HandlerRegistration addValueChangeHandler(
			ValueChangeHandler<Integer> handler) {
		return addHandler(handler, ValueChangeEvent.getType());
	}
}